import os

from flask import Flask, request, session
from config import Config
from src.exception import CustomException, UnauthorizedException
from src.pkg import HttpCode
from src.pkg.response import json, Response
from src.router import Router
from flask_cors import CORS
from flask_migrate import Migrate
from src.pkg.sqlalchemy import SQLAlchemy
from redis import Redis
from src.extension import redis_extension
from src.util.token_util import AccessToken


class Http(Flask):
    redis_client: Redis

    def __init__(self, *args, config: Config, db: SQLAlchemy, router: Router, migrate: Migrate, redis_client: Redis,
                 **kwargs):
        super().__init__(*args, **kwargs)
        self.config.from_object(config)
        self.register_error_handler(Exception, self._register_error_handler)
        self.before_request(self.check_login_status)
        self.redis_client = redis_client
        router.reg_router(self)
        db.init_app(self)
        print(os.getenv('REDIS_HOST'))
        redis_extension.init_app(self)
        migrate.init_app(self, db, directory="src/migration")
        CORS(self, resources={
            r"/*": {
                "origins": "*",
                "supports_credentials": True,
            },
        })

    # 登录验证拦截器
    def check_login_status(self):
        print("================================================================================")
        print(request.path)
        if request.path in ['/login', '/register', "/upload","/api/login","/api/register","/api/upload','/testAudo'"]:
            return  # 不拦截登录和注册页面

        token = request.headers.get('Authorization')
        if not token:
            raise UnauthorizedException("未登录")
        payload = AccessToken.decode_token(token, self.config["JWT_SECRET_KEY"], "HS256")
        if payload is None:
            raise UnauthorizedException("未登录")
        session['user_id'] = payload["user_id"]
        session['username'] = payload["username"]

    def _register_error_handler(self, error: Exception):
        print(error)
        # logging.error("An error occurred: %s", error, exc_info=True)
        if isinstance(error, CustomException):
            return json(
                Response(
                    code=error.code,
                    message=error.message,
                    data=error.data if error.data is not None else {},
                )
            )
        else:
            if self.debug:
                return error
            else:
                return json(Response(code=HttpCode.FAIL, message=str(error)))
